package com.qzsoft.zhjd.common.utils;


import cn.afterturn.easypoi.cache.ImageCache;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.vo.BaseEntityTypeConstants;
import cn.afterturn.easypoi.excel.export.base.BaseExportService;
import cn.afterturn.easypoi.excel.export.base.ExportCommonService;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import cn.afterturn.easypoi.exception.excel.ExcelExportException;
import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum;
import cn.afterturn.easypoi.util.PoiExcelGraphDataUtil;
import cn.afterturn.easypoi.util.PoiMergeCellUtil;
import cn.afterturn.easypoi.util.PoiPublicUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.util.*;

import static cn.afterturn.easypoi.excel.ExcelExportUtil.USE_SXSSF_LIMIT;
@Slf4j
public class CustomExcelExport extends ExportCommonService {

    private static int MAX_NUM = 60000;
    private Map<Integer, Double> statistics;
    private int currentIndex = 0;
    private static String TITLE_NAME = "title";
    private static String LIST_NAME = "list";
    protected IExcelExportStyler excelExportStyler;
    private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");

    protected ExcelType type = ExcelType.XSSF;

    public  static Workbook exportExcel(ExportParams entity, Class<?> pojoClass, Collection<?> dataSet, Object countNums) {
        org.apache.poi.ss.usermodel.Workbook workbook = getWorkbook(entity.getType(), dataSet.size());
        org.apache.poi.ss.usermodel.Sheet sheet = workbook.createSheet();
        org.apache.poi.ss.usermodel.Row row = sheet.createRow(0);
        row.setHeight(Short.parseShort(60*40+""));
        PoiMergeCellUtil.addMergedRegion(sheet, 0, 0, 0, 11);
        if(ObjectUtils.isNotEmpty(countNums)){
            Field[] declaredFields = countNums.getClass().getDeclaredFields();
            List<Map<String, Object>> cellData = new CustomExcelExport().getCellData(countNums);
            int cellNum = 0;
            for(int i = 0;i<cellData.size();i++){
                Set<String> strings = cellData.get(i).keySet();
                try {
                    for(String k:strings){
                        org.apache.poi.ss.usermodel.Cell cell = row.createCell(cellNum, CellType.STRING);
                        cell.setCellValue(k+":\n"+cellData.get(i).get(k));
                        ++cellNum;
                    }
                    } catch (Exception e) {
                        e.printStackTrace();
                }
            }
        }
        createSheet(workbook,sheet,1, entity, pojoClass, dataSet);
        return workbook;
    }

    public List<Map<String,Object>> getCellData(Object o){
        List<Map<String,Object>> result = new ArrayList<>();
        Field[] declaredFields = o.getClass().getDeclaredFields();
        try{
            StringBuffer sbf = new StringBuffer();
            Map<String,Object> insertTxt = new HashMap<>();
            for(Field f:declaredFields){
                f.setAccessible(true);
                Excel annotation = f.getAnnotation(Excel.class);
                if(null != annotation ){
                    sbf.append(annotation.name()+":"+f.get(o)+"\n");
//                    Map<String,Object> param = new HashMap<>();
//                    param.put(annotation.name(),f.get(o));
//                    result.add(param);
                }
            }
            insertTxt.put("统计数据",sbf.toString());
            result.add(insertTxt);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    private static void createSheet(Workbook workbook,Sheet sheet, int indexRow, ExportParams entity, Class<?> pojoClass, Collection<?> dataSet) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Excel export start ,class is {}", pojoClass);
            LOGGER.debug("Excel version is {}",
                    entity.getType().equals(ExcelType.HSSF) ? "03" : "07");
        }
        if (sheet == null || entity == null || pojoClass == null || dataSet == null) {
            throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR);
        }
        try {
            List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
//            IExcelI18nHandler i18nHandler = entity.getI18nHandler();
            // 得到所有字段
            Field[]     fileds   = PoiPublicUtil.getClassFields(pojoClass);
            ExcelTarget etarget  = pojoClass.getAnnotation(ExcelTarget.class);
            String      targetId = etarget == null ? null : etarget.value();
            CustomExcelExport customExcelExport = new CustomExcelExport();
            customExcelExport.type = entity.getType();
            customExcelExport.getAllExcelField(entity.getExclusions(), targetId, fileds, excelParams, pojoClass,
                    null, null);
            //获取所有参数后,后面的逻辑判断就一致了
            customExcelExport.insertDataToSheet(workbook,indexRow,entity, excelParams, dataSet,sheet);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage(), e);
            throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e);
        }
    }

    protected void insertDataToSheet(Workbook workbook,int indexRow,ExportParams entity,
                                     List<ExcelExportEntity> entityList, Collection<?> dataSet,
                                     Sheet sheet) {
        try {
            dataHandler = entity.getDataHandler();
            if (dataHandler != null && dataHandler.getNeedHandlerFields() != null) {
                needHandlerList = Arrays.asList(dataHandler.getNeedHandlerFields());
            }
            dictHandler = entity.getDictHandler();
            // 创建表格样式
            setExcelExportStyler((IExcelExportStyler) entity.getStyle()
                    .getConstructor(Workbook.class).newInstance(workbook));
            Drawing                 patriarch   = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet);
            List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
            if (entity.isAddIndex()) {
                entityList.add(indexExcelEntity(entity));
            }
            sortAllParams(entityList);
            int index = indexRow;
            int titleHeight = index;
            setCellWith(entityList, sheet);
            setColumnHidden(entityList, sheet);
            short rowHeight = entity.getHeight() != 0 ? entity.getHeight() : getRowHeight(entityList);
            setCurrentIndex(1);
//            createAddressList(sheet, index, entityList, 0);
            this.createTitle(sheet, index, entityList, 0);
            Iterator<?>  its      = dataSet.iterator();
            List<Object> tempList = new ArrayList<Object>();
            while (its.hasNext()) {
                Object t = its.next();
                index += createCells(patriarch, index+1, t, entityList, sheet, workbook, rowHeight, 0)[0];
                JSONObject json=(JSONObject) JSONObject.toJSON(t);
                List ch = (List)json.get("children");
                if(!ObjectUtils.isEmpty(json.get("children"))){
                    for(int z = 0;z<ch.size();z++){
                        index += createCells(patriarch, index+1, JSON.parseObject(JSON.toJSONString(ch.get(z)),t.getClass()), entityList, sheet, workbook, rowHeight, 0)[0];
                    }
                }
                tempList.add(t);
                if (index >= MAX_NUM) {
                    break;
                }
            }
            if (entity.getFreezeCol() != 0) {
                sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0);
            }

            mergeCells(sheet, excelParams, titleHeight);

            its = dataSet.iterator();
            for (int i = 0, le = tempList.size(); i < le; i++) {
                its.next();
                its.remove();
            }
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("List data more than max ,data size is {}",
                        dataSet.size());
            }
            // 发现还有剩余list 继续循环创建Sheet
//            if (dataSet.size() > 0) {
//                createAddressList(workbook, entity, entityList, dataSet);
//            }

        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e);
        }
    }

        private void createTitle(Sheet sheet, int index, List<ExcelExportEntity> entityList, int i) {
            Drawing                 patriarch   = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet);
            if(entityList.size()>0){
                Row row = sheet.createRow(index);
                row.setHeight(Short.parseShort(30*20+""));
                for(int t = 0;t<entityList.size();t++){
                    Cell cell = row.createCell(i+t,CellType.STRING);
                    cell.setCellValue(entityList.get(i+t).getName());
                    cell.setCellStyle(this.getStyles(false, entityList.get(t)));
                }
            }
        }

    private int createAddressList(Sheet sheet, int index, List<ExcelExportEntity> excelParams, int cellIndex) {
        for (int i = 0; i < excelParams.size(); i++) {
//            if (excelParams.get(i).isAddressList()) {
//                ExcelExportEntity entity = excelParams.get(i);
//                CellRangeAddressList regions = new CellRangeAddressList(index,
//                        this.type.equals(ExcelType.XSSF) ? 1000000 : 65535, cellIndex, cellIndex);
//                sheet.addValidationData(sheet.getDataValidationHelper().createValidation(sheet.getDataValidationHelper().createExplicitListConstraint(getAddressListValues(entity)), regions));
//            }
            if (excelParams.get(i).getList() != null) {
                cellIndex = createAddressList(sheet, index, excelParams.get(i).getList(), cellIndex);
            } else {
                cellIndex++;
            }
        }
        return cellIndex;
    }
    private static org.apache.poi.ss.usermodel.Workbook getWorkbook(ExcelType type, int size) {
        if (ExcelType.HSSF.equals(type)) {
            return new HSSFWorkbook();
        } else {
            return (Workbook)(size < USE_SXSSF_LIMIT ? new XSSFWorkbook() : new SXSSFWorkbook());
        }
    }

    public static SXSSFWorkbook msgExportExcel(SXSSFWorkbook wb, CountTopData countNums)throws Exception {
        if (wb == null) {
            wb = new SXSSFWorkbook();
        }
        SXSSFSheet sheet = null;
        sheet = (SXSSFSheet) wb.createSheet("统计数据");
        File file = null;
        List<ExportListData> resultList = countNums.getCurlist();
        int size = resultList.size();//sheet数
        List<Map<String,Object>> legend = countNums.getLengend();
        try {
            for (int i = 0; i < size; i++) {

                int rowNum = 0;
                //写入标题
                if(countNums != null && !ObjectUtils.isEmpty(countNums.getCountDto())){
                    Row hrow = sheet.createRow(rowNum);
                    hrow.setHeight(Short.parseShort(50*30+""));
                    if(countNums.isFirstMerge()){
                        PoiMergeCellUtil.addMergedRegion(sheet, 0, 0, 0, 11);
                    }
                    Cell cell = hrow.createCell(0);
                    cell.setAsActiveCell();
                    Object o = countNums.getCountDto();
                    StringBuffer sbf = new StringBuffer("统计数据："+"\n");
                    Arrays.asList(o.getClass().getDeclaredFields()).stream().forEach(f -> {
                        Excel annotation = f.getAnnotation(Excel.class);
                        if(null != annotation ) {
                            f.setAccessible(true);
                            try {
                                if(!ObjectUtils.isEmpty(f.get(o))){
                                    sbf.append(annotation.name() + ":" + f.get(o) + "\n");
                                }
                            } catch (IllegalAccessException e) {
                                log.error("组装统计数据出现异常！");
                                RenExceptionUtils.throwEx("统计数据异常！");
                            }
                        }
                        cell.setCellValue(sbf.toString());
                    });
                }
                rowNum++;
                //创建图表
                file = ExportChartUtil.createPieChart("汇总统计",countNums);
                imageOut(wb, sheet, file);
                if(file.exists()){

                }
        }
            writeTypeListDate(wb,size,countNums);
            writePageListData(wb,size,countNums);

        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return wb;
    }

    public static void writeTypeListDate(SXSSFWorkbook wb,int pageNum,CountTopData countNums){
        int rowNum = 0;
        //写入列表数据
        List<ExportListData> curList = countNums.getCurlist();
        SXSSFSheet sheet = (SXSSFSheet) wb.createSheet(curList.get(0).getTitle());
        if(!ObjectUtils.isEmpty(curList)){
            if(!StringUtils.isBlank(curList.get(0).getTitle())){
                Row hrow = sheet.createRow(rowNum);
                hrow.createCell(0,CellType.STRING).setCellValue(curList.get(0).getTitle());
            }
            List<Object> list = curList.get(0).getList();
            if(list.get(0).getClass().isInstance(new HashMap<>())){
                for(int t = 0;t<list.size();t++){
                    ++rowNum;
                    Row row = sheet.createRow(rowNum);
                    for(Object k:((Map)list.get(t)).keySet()){
                        for(int s = 0;s<curList.get(0).getLegend().size();s++){
                            for(Object key:((Map)curList.get(0).getLegend().get(s)).keySet()){
                                if(key.equals(k)){
                                    row.createCell(s,CellType.STRING).setCellValue(String.valueOf(((Map)list.get(t)).get(key)));
                                }
                            }
                        }
                    }
                }
            } else{
                insertDataToSheet(wb,sheet,rowNum,countNums.getObjClass(),list);
            }
        }
    }

    public static void writePageListData(SXSSFWorkbook wb,int pageNum,CountTopData countTopData){
        int rowNum = 0;
        List<ExportListData> pageList = countTopData.getPageList();
        for(int t =0;t<pageList.size();t++){
            List<Object[]> data = new ArrayList<>();
            SXSSFSheet sheet = (SXSSFSheet) wb.createSheet(pageList.get(t).getTitle());
            ExportListData exportListData = pageList.get(t);
            List<Map<String, Object>> legend = exportListData.getLegend();
            SXSSFRow row = sheet.createRow(rowNum);
            for(int s = 0;s<legend.size();s++){
                for(String key:legend.get(s).keySet()){
                    row.createCell(s, CellType.STRING).setCellValue(String.valueOf(legend.get(s).get(key)));
                }
            }
            List<T> pageData = exportListData.getList();
            if(pageList.get(t).getClass().isInstance(new HashMap<>())){
                for(int s = 0;s<pageData.size();s++){
                    rowNum++;
                    SXSSFRow hrow = sheet.createRow(rowNum);
                    Object map = pageData.get(s);
                    for(Object key:((Map)map).keySet()){
                        for(int v = 0;v<legend.size();v++){
                            if(legend.get(v).keySet().contains(((Map)map).keySet())){
                                hrow.createCell(v,CellType.STRING).setCellValue(String.valueOf(((Map)map).get(key)));
                            }
                        }
                    }
                }
            }else{
                insertDataToSheet(wb,sheet,rowNum,countTopData.getObjClass(),pageData);
            }

        }
    }

    public static void insertDataToSheet(Workbook wb,Sheet sheet,int rowNum,Class<?> objClass,Collection<?> list){
        ExportParams params = new ExportParams("", "Page", ExcelType.HSSF);
        List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
//        IExcelI18nHandler i18nHandler = params.getI18nHandler();
        // 得到所有字段
        Field[]     fileds   = PoiPublicUtil.getClassFields(objClass);
        ExcelTarget etarget  = objClass.getAnnotation(ExcelTarget.class);
        String      targetId = etarget == null ? null : etarget.value();
        try {
            new CustomExcelExport().getAllExcelField(params.getExclusions(), targetId, fileds, excelParams, objClass,
                    null, null);
        } catch (Exception e) {
            log.error("列表读出数据异常！");
            RenExceptionUtils.throwEx("读出数据异常！");
        }
        //获取所有参数后,后面的逻辑判断就一致了
        new CustomExcelExport().insertDataToSheet(wb,rowNum,params, excelParams, list,sheet);
    }

    private static void imageOut(SXSSFWorkbook wb,SXSSFSheet sheet,File file) {

        ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
        BufferedImage bufferImg;
        try {
            bufferImg = ImageIO.read(file);
            ImageIO.write(bufferImg, "png", byteArrayOut);
            Drawing dp = sheet.createDrawingPatriarch();
            XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 512, 255, 0, 3, 10, 20);//设置图表在excel中位置
            anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_DONT_RESIZE);
            dp.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), wb.PICTURE_TYPE_PNG)).resize(0.8);
            if(file.exists()){
                file.delete();
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }

    }

    public int[] createCells(Drawing patriarch, int index, Object t, List<ExcelExportEntity> excelParams, Sheet sheet, Workbook workbook, short rowHeight, int cellNum) {
        try {
            Row row = sheet.getRow(index) == null ? sheet.createRow(index) : sheet.getRow(index);
            if (rowHeight != -1) {
                row.setHeight(rowHeight);
            }

            int maxHeight = 1;
            int listMaxHeight = 1;
            int margeCellNum = cellNum;
            int indexKey = this.createIndexCell(row, index, (ExcelExportEntity)excelParams.get(0));
            cellNum += indexKey;
            int k = indexKey;

            ExcelExportEntity entity;
            int paramSize;
            for(paramSize = excelParams.size(); k < paramSize; ++k) {
                entity = (ExcelExportEntity)excelParams.get(k);
                if (entity.getList() == null) {
                    Object value = this.getCellValue(entity, t);
                    if (entity.getType() == BaseEntityTypeConstants.STRING_TYPE) {
                        this.createStringCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? this.getStyles(false, entity) : this.getStyles(true, entity), entity);
                    } else if (entity.getType() == BaseEntityTypeConstants.DOUBLE_TYPE) {
                        this.createDoubleCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? this.getStyles(false, entity) : this.getStyles(true, entity), entity);
                    } else {
                        this.createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), t);
                    }

                    if (entity.isHyperlink()) {
                        row.getCell(cellNum - 1).setHyperlink(this.dataHandler.getHyperlink(row.getSheet().getWorkbook().getCreationHelper(), t, entity.getName(), value));
                    }
                } else {
                    Collection<?> list = this.getListCellValue(entity, t);
                    int listIndex = 0;
                    int tmpListHeight = 0;
                    if (list != null && list.size() > 0) {
                        int tempCellNum = 0;

                        for(Iterator var21 = list.iterator(); var21.hasNext(); ++listIndex) {
                            Object obj = var21.next();
                            int[] temp = this.createCells(patriarch, index + listIndex, obj, entity.getList(), sheet, workbook, rowHeight, cellNum);
                            tempCellNum = temp[1];
                            tmpListHeight += temp[0];
                        }

                        cellNum = tempCellNum;
                        listMaxHeight = Math.max(listMaxHeight, tmpListHeight);
                    }
                }
            }

             maxHeight = maxHeight + (listMaxHeight - 1);
            if (indexKey == 1 && ((ExcelExportEntity)excelParams.get(1)).isNeedMerge()) {
                ((ExcelExportEntity)excelParams.get(0)).setNeedMerge(true);
            }

            k = indexKey;

            for(paramSize = excelParams.size(); k < paramSize; ++k) {
                entity = (ExcelExportEntity)excelParams.get(k);
                if (entity.getList() != null) {
                    margeCellNum += entity.getList().size();
                } else if (entity.isNeedMerge() && maxHeight > 1) {
                    for(int i = index + 1; i < index + maxHeight; ++i) {
                        if (sheet.getRow(i) == null) {
                            sheet.createRow(i);
                        }

                        sheet.getRow(i).createCell(margeCellNum);
                        sheet.getRow(i).getCell(margeCellNum).setCellStyle(this.getStyles(false, entity));
                    }

                    PoiMergeCellUtil.addMergedRegion(sheet, index, index + maxHeight - 1, margeCellNum, margeCellNum);
                    ++margeCellNum;
                }
            }

            return new int[]{maxHeight, cellNum};
        } catch (Exception var24) {
            LOGGER.error("excel cell export error ,data is :{}", ReflectionToStringBuilder.toString(t));
            LOGGER.error(var24.getMessage(), var24);
            throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, var24);
        }
    }

    public void createImageCell(Drawing patriarch, ExcelExportEntity entity, Row row, int i, String imagePath, Object obj) throws Exception {
        Cell cell = row.createCell(i);
        byte[] value = null;
        if (entity.getExportImageType() != 1) {
            value = (byte[])((byte[])(entity.getMethods() != null ? this.getFieldBySomeMethod(entity.getMethods(), obj) : entity.getMethod().invoke(obj)));
        }

        this.createImageCell(cell, 50.0D * entity.getHeight(), entity.getExportImageType() == 1 ? imagePath : null, value);
    }

    public void createImageCell(Cell cell, double height, String imagePath, byte[] data) throws Exception {
        if (height > (double)cell.getRow().getHeight()) {
            cell.getRow().setHeight((short)((int)height));
        }

        Object anchor;
        if (this.type.equals(ExcelType.HSSF)) {
            anchor = new HSSFClientAnchor(0, 0, 0, 0, (short)cell.getColumnIndex(), cell.getRow().getRowNum(), (short)(cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
        } else {
            anchor = new XSSFClientAnchor(0, 0, 0, 0, (short)cell.getColumnIndex(), cell.getRow().getRowNum(), (short)(cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
        }

        if (org.apache.commons.lang3.StringUtils.isNotEmpty(imagePath)) {
            data = ImageCache.getImage(imagePath);
        }

        if (data != null) {
            PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture((ClientAnchor)anchor, cell.getSheet().getWorkbook().addPicture(data, this.getImageType(data)));
        }

    }

    public void createImageCell(Cell cell, double height, int rowspan, int colspan, String imagePath, byte[] data) throws Exception {
        if (height > (double)cell.getRow().getHeight()) {
            cell.getRow().setHeight((short)((int)height));
        }

        Object anchor;
        if (this.type.equals(ExcelType.HSSF)) {
            anchor = new HSSFClientAnchor(0, 0, 0, 0, (short)cell.getColumnIndex(), cell.getRow().getRowNum(), (short)(cell.getColumnIndex() + colspan), cell.getRow().getRowNum() + rowspan);
        } else {
            anchor = new XSSFClientAnchor(0, 0, 0, 0, (short)cell.getColumnIndex(), cell.getRow().getRowNum(), (short)(cell.getColumnIndex() + colspan), cell.getRow().getRowNum() + rowspan);
        }

        if (org.apache.commons.lang3.StringUtils.isNotEmpty(imagePath)) {
            data = ImageCache.getImage(imagePath);
        }

        if (data != null) {
            PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture((ClientAnchor)anchor, cell.getSheet().getWorkbook().addPicture(data, this.getImageType(data)));
        }

    }

    private int createIndexCell(Row row, int index, ExcelExportEntity excelExportEntity) {
        if (excelExportEntity.getFormat() != null && excelExportEntity.getFormat().equals("isAddIndex")) {
            this.createStringCell(row, 0, this.currentIndex + "", index % 2 == 0 ? this.getStyles(false, (ExcelExportEntity)null) : this.getStyles(true, (ExcelExportEntity)null), (ExcelExportEntity)null);
            ++this.currentIndex;
            return 1;
        } else {
            return 0;
        }
    }

    public void createListCells(Drawing patriarch, int index, int cellNum, Object obj, List<ExcelExportEntity> excelParams, Sheet sheet, Workbook workbook, short rowHeight) throws Exception {
        Row row;
        if (sheet.getRow(index) == null) {
            row = sheet.createRow(index);
            if (rowHeight != -1) {
                row.setHeight(rowHeight);
            }
        } else {
            row = sheet.getRow(index);
            if (rowHeight != -1) {
                row.setHeight(rowHeight);
            }
        }

        int k = 0;

        for(int paramSize = excelParams.size(); k < paramSize; ++k) {
            ExcelExportEntity entity = (ExcelExportEntity)excelParams.get(k);
            Object value = this.getCellValue(entity, obj);
            if (entity.getType() == BaseEntityTypeConstants.STRING_TYPE) {
                this.createStringCell(row, cellNum++, value == null ? "" : value.toString(), row.getRowNum() % 2 == 0 ? this.getStyles(false, entity) : this.getStyles(true, entity), entity);
                if (entity.isHyperlink()) {
                    row.getCell(cellNum - 1).setHyperlink(this.dataHandler.getHyperlink(row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(), value));
                }
            } else if (entity.getType() == BaseEntityTypeConstants.DOUBLE_TYPE) {
                this.createDoubleCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? this.getStyles(false, entity) : this.getStyles(true, entity), entity);
                if (entity.isHyperlink()) {
                    row.getCell(cellNum - 1).setHyperlink(this.dataHandler.getHyperlink(row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(), value));
                }
            } else {
                this.createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), obj);
            }
        }

    }

    public void createStringCell(Row row, int index, String text, CellStyle style, ExcelExportEntity entity) {
        Cell cell = row.createCell(index);
        if (style != null && style.getDataFormat() > 0 && style.getDataFormat() < 12) {
            cell.setCellValue(Double.parseDouble(text));
            cell.setCellType(CellType.NUMERIC);
        } else {
            Object rtext;
            if (this.type.equals(ExcelType.HSSF)) {
                rtext = new HSSFRichTextString(text);
            } else {
                rtext = new XSSFRichTextString(text);
            }

            cell.setCellValue((RichTextString)rtext);
        }

        if (style != null) {
            cell.setCellStyle(style);
        }

        this.addStatisticsData(index, text, entity);
    }

    public void createDoubleCell(Row row, int index, String text, CellStyle style, ExcelExportEntity entity) {
        Cell cell = row.createCell(index);
        cell.setCellType(CellType.NUMERIC);
        if (text != null && text.length() > 0) {
            try {
                cell.setCellValue(Double.parseDouble(text));
            } catch (NumberFormatException var8) {
                cell.setCellType(CellType.STRING);
                cell.setCellValue(text);
            }
        }

        if (style != null) {
            cell.setCellStyle(style);
        }

        this.addStatisticsData(index, text, entity);
    }

    public void addStatisticsRow(CellStyle styles, Sheet sheet) {
        if (this.statistics.size() > 0) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("add statistics data ,size is {}", this.statistics.size());
            }

            Row row = sheet.createRow(sheet.getLastRowNum() + 1);
            Set<Integer> keys = this.statistics.keySet();
            this.createStringCell(row, 0, "合计", styles, (ExcelExportEntity)null);
            Iterator var5 = keys.iterator();

            while(var5.hasNext()) {
                Integer key = (Integer)var5.next();
                this.createStringCell(row, key, DOUBLE_FORMAT.format(this.statistics.get(key)), styles, (ExcelExportEntity)null);
            }

            this.statistics.clear();
        }

    }

    private void addStatisticsData(Integer index, String text, ExcelExportEntity entity) {
        if (entity != null && entity.isStatistics()) {
            Double temp = 0.0D;
            if (!this.statistics.containsKey(index)) {
                this.statistics.put(index, temp);
            }

            try {
                temp = Double.valueOf(text);
            } catch (NumberFormatException var6) {
            }

            this.statistics.put(index, (Double)this.statistics.get(index) + temp);
        }

    }

    public int getImageType(byte[] value) {
        String type = PoiPublicUtil.getFileExtendName(value);
        if ("JPG".equalsIgnoreCase(type)) {
            return 5;
        } else {
            return "PNG".equalsIgnoreCase(type) ? 6 : 5;
        }
    }

    private Map<Integer, int[]> getMergeDataMap(List<ExcelExportEntity> excelParams) {
        Map<Integer, int[]> mergeMap = new HashMap();
        int i = 0;
        Iterator var4 = excelParams.iterator();

        while(true) {
            while(var4.hasNext()) {
                ExcelExportEntity entity = (ExcelExportEntity)var4.next();
                if (entity.isMergeVertical()) {
                    mergeMap.put(i, entity.getMergeRely());
                }

                if (entity.getList() != null) {
                    for(Iterator var6 = entity.getList().iterator(); var6.hasNext(); ++i) {
                        ExcelExportEntity inner = (ExcelExportEntity)var6.next();
                        if (inner.isMergeVertical()) {
                            mergeMap.put(i, inner.getMergeRely());
                        }
                    }
                } else {
                    ++i;
                }
            }

            return mergeMap;
        }
    }

    public CellStyle getStyles(boolean needOne, ExcelExportEntity entity) {
        return this.excelExportStyler.getStyles(needOne, entity);
    }

    public void mergeCells(Sheet sheet, List<ExcelExportEntity> excelParams, int titleHeight) {
        Map<Integer, int[]> mergeMap = this.getMergeDataMap(excelParams);
        PoiMergeCellUtil.mergeCells(sheet, mergeMap, titleHeight);
    }

    public void setCellWith(List<ExcelExportEntity> excelParams, Sheet sheet) {
        int index = 0;

        for(int i = 0; i < excelParams.size(); ++i) {
            if (((ExcelExportEntity)excelParams.get(i)).getList() != null) {
                List<ExcelExportEntity> list = ((ExcelExportEntity)excelParams.get(i)).getList();

                for(int j = 0; j < list.size(); ++j) {
                    sheet.setColumnWidth(index, (int)(256.0D * ((ExcelExportEntity)list.get(j)).getWidth()));
                    ++index;
                }
            } else {
                sheet.setColumnWidth(index, (int)(256.0D * ((ExcelExportEntity)excelParams.get(i)).getWidth()));
                ++index;
            }
        }

    }

    public void setColumnHidden(List<ExcelExportEntity> excelParams, Sheet sheet) {
        int index = 0;

        for(int i = 0; i < excelParams.size(); ++i) {
            if (((ExcelExportEntity)excelParams.get(i)).getList() != null) {
                List<ExcelExportEntity> list = ((ExcelExportEntity)excelParams.get(i)).getList();

                for(int j = 0; j < list.size(); ++j) {
                    sheet.setColumnHidden(index, ((ExcelExportEntity)list.get(j)).isColumnHidden());
                    ++index;
                }
            } else {
                sheet.setColumnHidden(index, ((ExcelExportEntity)excelParams.get(i)).isColumnHidden());
                ++index;
            }
        }

    }

    public void setCurrentIndex(int currentIndex) {
        this.currentIndex = currentIndex;
    }

    public void setExcelExportStyler(IExcelExportStyler excelExportStyler) {
        this.excelExportStyler = excelExportStyler;
    }

    public IExcelExportStyler getExcelExportStyler() {
        return this.excelExportStyler;
    }

}
